// SelectComputerDialog.cpp : implementation file
//

#include "stdafx.h"
#include "SelectComputerDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#include <iterator>
#include <algorithm>

namespace
{
	LPCTSTR NO_DOMAIN_WARNING = _T("Domains informations not found !");
	
	LPCTSTR NO_DOMAIN_ITEM = _T("(NONE)");
	LPCTSTR ALL_DOMAINS_ITEM = _T("(ALL DOMAINS)");
}


/////////////////////////////////////////////////////////////////////////////
// CSelectComputerDialog dialog


CSelectComputerDialog::CSelectComputerDialog(CWnd* pParent /*=NULL*/)
	: CDialog(CSelectComputerDialog::IDD, pParent),
	m_bSingleSelection(true),
	m_bOnlyOneDomainInTime(true)
{
	//create image list	
	m_imagelist.Create(::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), ILC_COLOR, 0, 0);	
	//add two images to image list
	m_imagelist.Add(AfxGetApp()->LoadIcon(MAKEINTRESOURCE(IDI_SELECT_COMPUTER_USER)));
	m_imagelist.Add(AfxGetApp()->LoadIcon(MAKEINTRESOURCE(IDI_SELECT_COMPUTER_USERS)));

	//{{AFX_DATA_INIT(CSelectComputerDialog)
	//}}AFX_DATA_INIT
}


void CSelectComputerDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CSelectComputerDialog)
	DDX_Control(pDX, IDC_LIST, m_lstComputers);
	DDX_Control(pDX, IDC_COMBO, m_cmbLookIn);
	DDX_Control(pDX, IDOK,	m_btnOK);
	DDX_Control(pDX, IDCANCEL, m_btnCancel);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CSelectComputerDialog, CDialog)
	//{{AFX_MSG_MAP(CSelectComputerDialog)
	ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST, OnItemchangedList)
	ON_CBN_SELCHANGE(IDC_COMBO, OnSelchangeCombo)
	ON_WM_PAINT()
	ON_WM_SHOWWINDOW()
	ON_WM_SIZE()
	ON_WM_SIZING()
	ON_CBN_DROPDOWN(IDC_COMBO, OnDropdownCombo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSelectComputerDialog message handlers

void CSelectComputerDialog::OnItemchangedList(NMHDR* pNMHDR, LRESULT* pResult) 
{
	UNUSED_ALWAYS(pNMHDR);

	const UINT uiSelectedCount = m_lstComputers.GetSelectedCount();
	m_btnOK.EnableWindow(uiSelectedCount);

	if (uiSelectedCount)
	{
		m_Names.clear();

		POSITION pos = m_lstComputers.GetFirstSelectedItemPosition();
		
		while (pos)
		{
			const int nItem = m_lstComputers.GetNextSelectedItem(pos);
			m_Names.push_back(make_pair( m_lstComputers.GetItemText(nItem, 0), m_lstComputers.GetItemText(nItem, 1)));
		}
	}
	
	*pResult = 0;
}

BOOL CSelectComputerDialog::OnInitDialog() 
{
	CDialog::OnInitDialog();

	InitResizeService();

	InitListControl();

	if (InitComboBox())
		RefreshListControl(m_vecstrDomains[0]);

	InvalidateRect(NULL);
		 
	return 	TRUE;
}

void CSelectComputerDialog::RefreshListControl(const basic_string<TCHAR>& strDomain)
{
	m_lstComputers.DeleteAllItems();

	//we need all users from all domains
	vector<basic_string<TCHAR> >::const_iterator bci, eci;
	if (!m_bOnlyOneDomainInTime && (strDomain == ALL_DOMAINS_ITEM))
	{
		++(bci = m_vecstrDomains.begin());
		eci = m_vecstrDomains.end();
	}
	else
	{	
		bci = eci = find(m_vecstrDomains.begin(), m_vecstrDomains.end(), strDomain);
		++eci;
	}

	for (; bci != eci; ++bci)
	{
		m_vecstrServers.clear();

		bool bResult = m_Network.GetServers(*bci, m_vecstrServers);
		ASSERT(bResult);

		//////////////////////////////////////////////////////////////////////////////	
		//Insert items (user names) into list view
		for (std::vector<basic_string<TCHAR> >::const_iterator ci = m_vecstrServers.begin();
			ci != m_vecstrServers.end(); ++ci)
		{
			m_lstComputers.InsertItem(m_lstComputers.GetItemCount(), ci->c_str(), 0);
			m_lstComputers.SetItemText(m_lstComputers.GetItemCount() - 1, 1, bci->c_str());
		}
		//~Insert items (user names)  into list view
	}	
}

void CSelectComputerDialog::OnSelchangeCombo() 
{
	CString strDomain;
	m_cmbLookIn.GetLBText(m_cmbLookIn.GetCurSel(), strDomain);

	RefreshListControl(static_cast<LPCTSTR>(strDomain));
}

void CSelectComputerDialog::OnPaint() 
{
	CDialog::OnPaint();

    CRect rc; 
    GetClientRect(rc); 
    rc.left = rc.right	- ::GetSystemMetrics(SM_CXHSCROLL); 
    rc.top	= rc.bottom - ::GetSystemMetrics(SM_CYVSCROLL); 
    CClientDC dc(this); 
    dc.DrawFrameControl( rc, DFC_SCROLL, DFCS_SCROLLSIZEGRIP ); 
}

void CSelectComputerDialog::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	if (m_pSizerCollection.get())
		m_pSizerCollection->RecalcLayout(cx, cy);

}

void CSelectComputerDialog::OnSizing(UINT fwSide, LPRECT pRect) 
{
	CDialog::OnSizing(fwSide, pRect);
	if (m_pSizerCollection.get())
		m_pSizerCollection->VerifyDragRectangle(fwSide, reinterpret_cast<LPARAM>(pRect));

	InvalidateRect(NULL);
}

void CSelectComputerDialog::OnDropdownCombo() 
{
	for (int i = 0; i < m_lstComputers.GetItemCount(); ++i)
		m_lstComputers.SetItemState(i, 0, LVIS_SELECTED);
}


void CSelectComputerDialog::InitResizeService()
{
	auto_ptr<CSizerCollection> aptr(new CSizerCollection(m_hWnd));
	m_pSizerCollection = aptr;

//Add CSizer objects to container to provide right controls placement
//on dialog resizing
///////////////////////////////////////////////////////////////////////////////
	m_pSizerCollection->Add(new CSizer(m_cmbLookIn.GetSafeHwnd(), GetSafeHwnd(), CSizer::HORIZONTAL));
	m_pSizerCollection->Add(new CSizer(m_lstComputers.GetSafeHwnd(), GetSafeHwnd(), CSizer::BOTH));
	m_pSizerCollection->Add(new CSizer(m_btnOK.GetSafeHwnd(), GetSafeHwnd(), CSizer::FIXED));
	m_pSizerCollection->Add(new CSizer(m_btnCancel.GetSafeHwnd(), GetSafeHwnd(), CSizer::FIXED));
///////////////////////////////////////////////////////////////////////////////
}

void CSelectComputerDialog::InitListControl()
{
	m_lstComputers.ModifyStyle(0, m_bSingleSelection ? LVS_SINGLESEL : 0, 0);
	
	//set image list for list control
	m_lstComputers.SetImageList(&m_imagelist, LVSIL_SMALL);

	CRect rect;
	m_lstComputers.GetWindowRect(&rect);

	LVCOLUMN lvCol;
	lvCol.mask = LVCF_FMT | LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
	lvCol.fmt = LVCFMT_LEFT;
	lvCol.cx = (rect.Width() - ::GetSystemMetrics(SM_CXVSCROLL) - ::GetSystemMetrics(SM_CXEDGE)) / 2 - 1;
	
	lvCol.iSubItem = 0;
	lvCol.pszText = _T("Name");
	m_lstComputers.InsertColumn(0, &lvCol);

//	lvCol.cx = 
	lvCol.iSubItem = 1;
	lvCol.pszText = _T("In Folder");
	m_lstComputers.InsertColumn(1, &lvCol);
}

bool CSelectComputerDialog::InitComboBox()
{
	//set image list for combobox control
	m_cmbLookIn.SetImageList(&m_imagelist);

	bool bResult = m_Network.GetDomains(m_vecstrDomains);
	ASSERT(bResult);

	COMBOBOXEXITEM cbItem;
	cbItem.mask = CBEIF_TEXT | CBEIF_IMAGE | CBEIF_SELECTEDIMAGE;
	cbItem.iImage = cbItem.iSelectedImage = 1;
	cbItem.iItem = -1;

	if (m_vecstrDomains.empty())
	{
		CString strTitle;
		GetWindowText(strTitle);
		MessageBox(NO_DOMAIN_WARNING, strTitle, MB_OK | MB_ICONWARNING);

		cbItem.pszText = const_cast<LPTSTR>(NO_DOMAIN_ITEM);

		//insert "No Domain" item
		m_cmbLookIn.InsertItem(&cbItem);

		//disable list control - 'coz we have no users to select
		m_lstComputers.EnableWindow(FALSE);
		m_cmbLookIn.SetCurSel(0);
		m_cmbLookIn.EnableWindow(FALSE);
	
		return false;
	}
	
//Add Items (domains names) into ComboBox
	if (!m_bOnlyOneDomainInTime)
		m_vecstrDomains.insert(m_vecstrDomains.begin(), ALL_DOMAINS_ITEM);

	for (vector<basic_string<TCHAR> >::const_iterator ci = m_vecstrDomains.begin(); 
		 ci != m_vecstrDomains.end(); ++ci)
	{
		cbItem.pszText = const_cast<LPTSTR>(ci->c_str());
		m_cmbLookIn.InsertItem(&cbItem);
	}
//~Add Items (domains names) into ComboBox
	
///////////////////////////////////////////////////////////////////////////////
//Set Selection in combo box item to the First(0) Item ..
	m_cmbLookIn.SetCurSel(0);

	return true;
}
